#include "Font.h"

namespace GenBen {

#pragma pack(1)

struct SimpleChar
{
	byte id, x, y, width, height, xoffset, yoffset, xadvance;
};

#pragma pack()


Font::Font(Graphics* graphics, const GenBen::string &filename)
	: graphics(graphics)
{
	ASSERT(graphics);
	ASSERT(sizeof(SimpleChar) == 8);

	memset(&desc, 0, sizeof(FontDesc));
	
	FILE* font_file = fopen(filename.c_str(), "rb");

	uint magic;

	fread(&magic, sizeof(uint), 1, font_file);

	ASSERT(magic == ( 'F'+('O'<<8)+('N'<<16)+('T'<<24) ));

	fread(&desc.line_height, 1, 1, font_file);
	
	string tex_filename = ""; 
	
	byte str_length, c;
	fread(&str_length, 1, 1, font_file);
	for(uint i = 0; i < str_length; ++i)
	{
		fread(&c, 1, 1, font_file);
		tex_filename += (char)c;
	}

	desc.font_texture = graphics->loadTexture(tex_filename);

	byte chars;
	fread(&chars, 1, 1, font_file);

	SimpleChar schar;
	for(uint i = 0; i < chars; ++i)
	{
		fread(&schar, sizeof(SimpleChar), 1, font_file);

		desc.chars[schar.id].source = RectI((int)schar.x, (int)schar.y, (int)schar.x + (int)schar.width, (int)schar.y + (int)schar.height);
		desc.chars[schar.id].x_offset = (uint)schar.xoffset;
		desc.chars[schar.id].y_offset = (uint)schar.yoffset;
		desc.chars[schar.id].x_advance = (uint)schar.xadvance;
	}
}

Font::~Font()
{
}

void Font::draw(const string& text, int layer, const VectorI& position, const Color& color)
{
	VectorI cursor = position;
	for(uint i = 0; i < text.size(); ++i)
	{
		if(text[i] < 32)
			continue;
	
		VectorI pos = cursor;
		pos.x += desc.chars[(size_t)text[i]].x_offset;
		pos.y += desc.chars[(size_t)text[i]].y_offset;

		graphics->draw(desc.font_texture, layer, desc.chars[(size_t)text[i]].source, pos, color);

		cursor.x += desc.chars[(size_t)text[i]].x_advance;
	}
}

uint Font::getHeight()
{
	return desc.line_height;
}

uint Font::getWidth(const string& text)
{
	uint width = 0;
	for(uint i = 0; i < text.size(); ++i)
	{
		if(text[i] < 32)
			continue;

		width += desc.chars[(size_t)text[i]].x_advance;
	}

	return width;
}

} // namespace
